package cn.tedu.luban.worker.main.repository;

import cn.tedu.luban.worker.main.converter.WorkerConverter;
import cn.tedu.luban.worker.main.mapper.WorkerMapper;
import cn.tedu.luban.worker.protocol.bo.AdminWorkerBO;
import cn.tedu.luban.worker.protocol.bo.FrontWorkerBO;
import cn.tedu.luban.worker.protocol.dos.WorkerDO;
import cn.tedu.luban.worker.protocol.param.WorkerParam;
import cn.tedu.luban.worker.protocol.param.WorkerRegistParam;
import cn.tedu.luban.worker.protocol.query.WorkerDBPageQuery;
import cn.tedu.luban.worker.protocol.query.WorkerListQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Repository
@Slf4j
public class WorkerRepoImpl implements WorkerRepository{

    @Autowired
    private WorkerMapper workerMapper;

    private static final String WORKER_DETAIL_PREFIX = "luban:worker:detail:";

    @Override
    public void delete(Long userId) {
        // delete form worker where user_id=#{userId}
        workerMapper.deleteByUserId(userId);

        redisTemplate.delete(WORKER_DETAIL_PREFIX + userId);
    }

    @Autowired
    private WorkerConverter workerConverter;

    @Override
    public Long save(WorkerRegistParam param) {

        // param里的师傅数据取出转换成workerDO
        /*
        param直接获取的参数四个:
            "idCard"、"phone"、"realName"、"userId"
        默认值：
            status、cert_status、audit_status
        通用6个字段:
            创建人id,创建人姓名,创建时间,修改人id,修改人姓名,修改时间
         */
        WorkerDO workerDO = workerConverter.param2do(param);

        workerMapper.insert(workerDO);
        return workerDO.getId();
    }

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public FrontWorkerBO getWorkerByUserId(Long userId) {
        // 获取值操作器
        ValueOperations valueOperations = redisTemplate.opsForValue();

        // 1.查询缓存
        String workerKey = WORKER_DETAIL_PREFIX + userId;
        // 是否命中
        Boolean hasKey = redisTemplate.hasKey(workerKey);

        FrontWorkerBO workerBO = null;

        if(!hasKey){
            // 缓存没命中 数据库查询
            WorkerDO workerDO = workerMapper.selectByUserId(userId);
            workerBO = workerConverter.do2frontBo(workerDO);
            // 补充缓存(是否永久存储) 设置超时时间1天
            valueOperations.set(workerKey,workerBO,60*60*24 + new Random().nextInt(60*60*12), TimeUnit.SECONDS);
        }else{
            // 直接读取缓存数据
            workerBO = (FrontWorkerBO)valueOperations.get(workerKey);
        }
        return workerBO;
    }

    @Override
    public Long countWorker(WorkerListQuery query) {
        // 入参 query 对象转换
        WorkerDBPageQuery workerDBPageQuery = workerConverter.query2dbQuery(query);
        // 查询总行数
        Long total = workerMapper.countWorker(workerDBPageQuery);
        return total;
    }

    @Override
    public List<AdminWorkerBO> findPageWorkers(WorkerListQuery query) {
        // 入参 query 对象转换
        WorkerDBPageQuery workerDBPageQuery = workerConverter.query2dbQuery(query);
        List<WorkerDO> dos = workerMapper.selectWorkers(workerDBPageQuery);
        List<AdminWorkerBO> adminWorkerBOS = workerConverter.dos2bos(dos);
        return adminWorkerBOS;
    }

    @Override
    public AdminWorkerBO findAdminWorker(Long userId) {
        WorkerDO workerDO = workerMapper.selectByUserId(userId);
        return workerConverter.do2bo(workerDO);
    }

    @Override
    public void updateAuditStatus(WorkerParam workerParam) {
        WorkerDO workerDO = workerConverter.param2do(workerParam);
        workerMapper.updateAuditStatus(workerDO);
        // 缓存与数据库 数据一致性
        redisTemplate.delete(WORKER_DETAIL_PREFIX + workerParam.getUserId());
    }

    @Override
    public void updateCertStatus(WorkerParam workerParam) {
        WorkerDO workerDO = workerConverter.param2do(workerParam);
        workerMapper.updateCertStatus(workerDO);
        // 缓存与数据库 数据一致性
        redisTemplate.delete(WORKER_DETAIL_PREFIX + workerParam.getUserId());
    }
}




